/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.serialversion; import java.io.*; import java.util.*; import org.openide.cookies.OpenCookie; import org.openide.src.*; import org.openide.util.RequestProcessor; import org.openide.windows.TopComponent; // [PENDING] localization /** Shows dialog to change serial version UID stuff. * * @author Jesse Glick */ public class SerialPrompts extends javax.swing.JPanel { List sortedPrompts; // List<PromptableItem> /** * @associates Boolean */ List changeSvuid; // List<Boolean> /** * @associates Boolean */ List changeJavadoc; // List<Boolean> List members; // List<List<MemberInfo> or null> int size; int considered; int curr; int currMember; PrintWriter pw; Runnable closer; private static final String UNDOCD = "[undocumented]"; // [PENDING] private static final class MemberInfo { String name; String doc; boolean isMethod; MemberElement element; } public SerialPrompts (Set prompts, PrintWriter pw, Runnable closer) { initComponents (); javax.swing.ButtonGroup group = new javax.swing.ButtonGroup (); group.add (leavejavadocalone); group.add (changejavadoc); this.pw = pw; this.closer = closer; size = prompts.size (); sortedPrompts = new ArrayList (prompts); Collections.sort (sortedPrompts, new Comparator () { public int compare (Object o1, Object o2) { return ((PromptableItem) o1).className.compareTo (((PromptableItem) o2).className); } }); changeSvuid = new ArrayList (size); int i; for (i = 0; i < size; i++) { PromptableItem pi = (PromptableItem) sortedPrompts.get (i); changeSvuid.add (new Boolean ((pi.currSvuid == 0) ^ (pi.idealSvuid == 0))); } changeJavadoc = new ArrayList (size); for (i = 0; i < size; i++) changeJavadoc.add (Boolean.FALSE); members = new ArrayList (size); for (i = 0; i < size; i++) members.add (null); curr = 0; currMember = -1; considered = 0; refresh (); } private static final String[] specialMethodNames = { "readObject", "writeObject", "readExternal", "writeExternal" }; private static final Class[][] specialMethodArgs = { { ObjectInputStream.class }, { ObjectOutputStream.class }, { ObjectInput.class }, { ObjectOutput.class } }; private static final int specialMethodCount = specialMethodNames.length; private static boolean refreshing = false; private void refresh () { refreshing = true; int i; PromptableItem pi = (PromptableItem) sortedPrompts.get (curr); prevbutton.setEnabled (curr > 0); nextbutton.setEnabled (curr < size - 1); numbering.setText ((curr + 1) + "/" + size); // [PENDING] classname.setText (pi.className); currsvuid.setText (pi.currSvuid == 0 ? "N/A" : Long.toString (pi.currSvuid) + "L"); // [PENDING] newsvuid.setText (pi.idealSvuid == 0 ? "N/A" : Long.toString (pi.idealSvuid) + "L"); // [PENDING] boolean thisChangeJavadoc = ((Boolean) changeJavadoc.get (curr)).booleanValue (); boolean thisChangeSvuid = ((Boolean) changeSvuid.get (curr)).booleanValue (); changesvuid.setSelected (thisChangeSvuid); (thisChangeJavadoc ? changejavadoc : leavejavadocalone).setSelected (true); if (members.get (curr) == null) { List thisMembers = new ArrayList (); // [PENDING] sort fields first for (i = 0; i < pi.fields.length; i++) { String name = pi.fields[i].getName (); FieldElement fe = pi.clazz.getField (Identifier.create (name)); if (fe != null) { MemberInfo mi = new MemberInfo (); thisMembers.add (mi); mi.name = name; mi.isMethod = false; JavaDocTag[] tags = fe.getJavaDoc ().getTags ("@serial"); if (tags.length > 1) pw.println ("Warning: " + fe + " has >1 @serial tags, only first will be used"); // [PENDING] mi.doc = (tags.length > 0 ? tags[0].text () : UNDOCD); mi.element = fe; } else { pw.println ("Warning: field " + name + " not found in class parse, will ignore"); // [PENDING] } } for (i = 0; i < specialMethodCount; i++) { String methodName = specialMethodNames[i]; Class[] methodArgs = specialMethodArgs[i]; Type[] methodArgsAsTypes = new Type[methodArgs.length]; for (int j = 0; j < methodArgs.length; j++) methodArgsAsTypes[j] = Type.createFromClass (methodArgs[j]); MethodElement me = pi.clazz.getMethod (Identifier.create (methodName), methodArgsAsTypes); if (me != null) { MemberInfo mi = new MemberInfo (); thisMembers.add (mi); mi.name = methodName; mi.isMethod = true; JavaDocTag[] tags = me.getJavaDoc ().getTags ("@serialData"); if (tags.length > 1) pw.println ("Warning: " + me + " has >1 @serialData tags, only first will be used"); // [PENDING] mi.doc = (tags.length > 0 ? tags[0].text () : UNDOCD); mi.element = me; } } members.set (curr, thisMembers); considered++; if (considered == size) runbutton.setEnabled (true); } List thisMembers = (List) members.get (curr); if (thisMembers.size () == 0) { changejavadoc.setEnabled (false); leavejavadocalone.setSelected (true); memberlist.setEnabled (false); memberlist.removeAllItems (); javadocpane.setEnabled (false); javadocpane.setText (""); showmembersourcebutton.setEnabled (false); } else { changejavadoc.setEnabled (true); if (! thisChangeJavadoc) { memberlist.setEnabled (false); memberlist.removeAllItems (); javadocpane.setEnabled (false); javadocpane.setText (""); showmembersourcebutton.setEnabled (false); } else { memberlist.setEnabled (true); memberlist.removeAllItems (); for (i = 0; i < thisMembers.size (); i++) { MemberInfo mi = (MemberInfo) thisMembers.get (i); String toDisplay = mi.isMethod ? mi.name + "()" : mi.name; // [PENDING] memberlist.addItem (toDisplay); } memberlist.setSelectedIndex (currMember); if (currMember == -1) { javadocpane.setEnabled (false); javadocpane.setText (""); showmembersourcebutton.setEnabled (false); } else { MemberInfo mi = (MemberInfo) thisMembers.get (currMember); javadocpane.setEnabled (true); javadocpane.setText (mi.doc); showmembersourcebutton.setEnabled (true); } } } if (pi.clazz.getField (Identifier.create ("serialPersistentFields")) != null) extrafieldslabel.setText ("Extra persistent fields not supported by this wizard."); // [PENDING] else extrafieldslabel.setText ("No extra persistent fields."); // [PENDING] changesvuid.setEnabled ((pi.currSvuid != 0 || pi.idealSvuid != 0) && pi.currSvuid != pi.idealSvuid); refreshing = false; } private void saveCurrent () { changeSvuid.set (curr, new Boolean (changesvuid.isSelected ())); changeJavadoc.set (curr, new Boolean (changejavadoc.isSelected ())); if (currMember != -1) { List thisMembers = (List) members.get (curr); MemberInfo mi = (MemberInfo) thisMembers.get (currMember); mi.doc = javadocpane.getText (); } } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the FormEditor. */ private void initComponents () {//GEN-BEGIN:initComponents jPanel1 = new javax.swing.JPanel (); numbering = new javax.swing.JLabel (); classname = new javax.swing.JLabel (); showclasssourcebutton = new javax.swing.JButton (); jPanel2 = new javax.swing.JPanel (); prevbutton = new javax.swing.JButton (); nextbutton = new javax.swing.JButton (); runbutton = new javax.swing.JButton (); cancelbutton = new javax.swing.JButton (); jPanel3 = new javax.swing.JPanel (); serialpanel = new javax.swing.JPanel (); jLabel3 = new javax.swing.JLabel (); currsvuid = new javax.swing.JTextField (); jLabel4 = new javax.swing.JLabel (); newsvuid = new javax.swing.JTextField (); jLabel6 = new javax.swing.JLabel (); changesvuid = new javax.swing.JCheckBox (); fieldspanel = new javax.swing.JPanel (); leavejavadocalone = new javax.swing.JRadioButton (); changejavadoc = new javax.swing.JRadioButton (); jPanel6 = new javax.swing.JPanel (); memberlist = new javax.swing.JComboBox (); jScrollPane1 = new javax.swing.JScrollPane (); javadocpane = new javax.swing.JEditorPane (); showmembersourcebutton = new javax.swing.JButton (); extrafieldslabel = new javax.swing.JLabel (); setLayout (new java.awt.BorderLayout ()); jPanel1.setLayout (new java.awt.FlowLayout (1, 20, 5)); numbering.setText ("2/3"); jPanel1.add (numbering); classname.setText ("com.foo.Bar"); classname.setForeground (java.awt.Color.black); classname.setFont (new java.awt.Font ("Monospaced", 0, 18)); jPanel1.add (classname); showclasssourcebutton.setText ("Show source..."); showclasssourcebutton.addActionListener (new java.awt.event.ActionListener () { public void actionPerformed (java.awt.event.ActionEvent evt) { showclasssourcebuttonActionPerformed (evt); } } ); jPanel1.add (showclasssourcebutton); add (jPanel1, java.awt.BorderLayout.NORTH); jPanel2.setLayout (new java.awt.FlowLayout (1, 10, 5)); prevbutton.setText ("< Prev"); prevbutton.addActionListener (new java.awt.event.ActionListener () { public void actionPerformed (java.awt.event.ActionEvent evt) { prevbuttonActionPerformed (evt); } } ); jPanel2.add (prevbutton); nextbutton.setText ("Next >"); nextbutton.addActionListener (new java.awt.event.ActionListener () { public void actionPerformed (java.awt.event.ActionEvent evt) { nextbuttonActionPerformed (evt); } } ); jPanel2.add (nextbutton); runbutton.setText ("Go!"); runbutton.setEnabled (false); runbutton.addActionListener (new java.awt.event.ActionListener () { public void actionPerformed (java.awt.event.ActionEvent evt) { runbuttonActionPerformed (evt); } } ); jPanel2.add (runbutton); cancelbutton.setText ("Cancel"); cancelbutton.addActionListener (new java.awt.event.ActionListener () { public void actionPerformed (java.awt.event.ActionEvent evt) { cancelbuttonActionPerformed (evt); } } ); jPanel2.add (cancelbutton); add (jPanel2, java.awt.BorderLayout.SOUTH); jPanel3.setLayout (new java.awt.GridBagLayout ()); java.awt.GridBagConstraints gridBagConstraints1; serialpanel.setLayout (new java.awt.GridLayout (3, 2, 5, 5)); serialpanel.setBorder (new javax.swing.border.TitledBorder("Serial Version UID")); jLabel3.setText ("Current SVUID:"); serialpanel.add (jLabel3); currsvuid.setEditable (false); currsvuid.setFont (new java.awt.Font ("Monospaced", 0, 12)); currsvuid.setText ("N/A"); serialpanel.add (currsvuid); jLabel4.setText ("New SVUID:"); serialpanel.add (jLabel4); newsvuid.setEditable (false); newsvuid.setFont (new java.awt.Font ("Monospaced", 0, 12)); newsvuid.setText ("-3453624876L"); serialpanel.add (newsvuid); jLabel6.setText ("Change?"); serialpanel.add (jLabel6); changesvuid.setSelected (true); changesvuid.setEnabled (false); serialpanel.add (changesvuid); gridBagConstraints1 = new java.awt.GridBagConstraints (); gridBagConstraints1.gridx = 0; gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH; jPanel3.add (serialpanel, gridBagConstraints1); fieldspanel.setLayout (new java.awt.GridBagLayout ()); java.awt.GridBagConstraints gridBagConstraints2; fieldspanel.setBorder (new javax.swing.border.TitledBorder("Serialization Members")); leavejavadocalone.setSelected (true); leavejavadocalone.setText ("Leave Javadoc alone"); leavejavadocalone.addActionListener (new java.awt.event.ActionListener () { public void actionPerformed (java.awt.event.ActionEvent evt) { leavejavadocaloneActionPerformed (evt); } } ); gridBagConstraints2 = new java.awt.GridBagConstraints (); gridBagConstraints2.gridx = 0; gridBagConstraints2.gridy = 0; gridBagConstraints2.anchor = java.awt.GridBagConstraints.WEST; fieldspanel.add (leavejavadocalone, gridBagConstraints2); changejavadoc.setText ("Change Javadoc..."); changejavadoc.setEnabled (false); changejavadoc.addActionListener (new java.awt.event.ActionListener () { public void actionPerformed (java.awt.event.ActionEvent evt) { changejavadocActionPerformed (evt); } } ); gridBagConstraints2 = new java.awt.GridBagConstraints (); gridBagConstraints2.gridx = 0; gridBagConstraints2.gridy = 1; gridBagConstraints2.anchor = java.awt.GridBagConstraints.WEST; fieldspanel.add (changejavadoc, gridBagConstraints2); jPanel6.setLayout (new java.awt.GridBagLayout ()); java.awt.GridBagConstraints gridBagConstraints3; memberlist.setFont (new java.awt.Font ("Monospaced", 0, 12)); memberlist.setEnabled (false); memberlist.addActionListener (new java.awt.event.ActionListener () { public void actionPerformed (java.awt.event.ActionEvent evt) { memberlistActionPerformed (evt); } } ); gridBagConstraints3 = new java.awt.GridBagConstraints (); gridBagConstraints3.anchor = java.awt.GridBagConstraints.WEST; jPanel6.add (memberlist, gridBagConstraints3); jScrollPane1.setMinimumSize (new java.awt.Dimension(200, 100)); javadocpane.setPreferredSize (new java.awt.Dimension(200, 50)); javadocpane.setContentType ("text/html"); javadocpane.setText ("[undocumented]"); javadocpane.setMinimumSize (new java.awt.Dimension(200, 50)); javadocpane.setEnabled (false); jScrollPane1.setViewportView (javadocpane); gridBagConstraints3 = new java.awt.GridBagConstraints (); gridBagConstraints3.gridx = 0; gridBagConstraints3.gridy = 1; gridBagConstraints3.gridwidth = 2; gridBagConstraints3.fill = java.awt.GridBagConstraints.BOTH; jPanel6.add (jScrollPane1, gridBagConstraints3); showmembersourcebutton.setText ("Show source..."); showmembersourcebutton.setEnabled (false); showmembersourcebutton.addActionListener (new java.awt.event.ActionListener () { public void actionPerformed (java.awt.event.ActionEvent evt) { showmembersourcebuttonActionPerformed (evt); } } ); gridBagConstraints3 = new java.awt.GridBagConstraints (); gridBagConstraints3.anchor = java.awt.GridBagConstraints.EAST; jPanel6.add (showmembersourcebutton, gridBagConstraints3); gridBagConstraints2 = new java.awt.GridBagConstraints (); gridBagConstraints2.gridx = 0; gridBagConstraints2.gridy = 2; gridBagConstraints2.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints2.anchor = java.awt.GridBagConstraints.WEST; fieldspanel.add (jPanel6, gridBagConstraints2); extrafieldslabel.setText ("No extra fields."); gridBagConstraints2 = new java.awt.GridBagConstraints (); gridBagConstraints2.gridx = 0; gridBagConstraints2.gridy = 3; fieldspanel.add (extrafieldslabel, gridBagConstraints2); gridBagConstraints1 = new java.awt.GridBagConstraints (); gridBagConstraints1.gridx = 0; gridBagConstraints1.gridy = 1; gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH; jPanel3.add (fieldspanel, gridBagConstraints1); add (jPanel3, java.awt.BorderLayout.CENTER); }//GEN-END:initComponents private void memberlistActionPerformed (java.awt.event.ActionEvent evt) {//GEN-FIRST:event_memberlistActionPerformed if (refreshing) return; saveCurrent (); currMember = memberlist.getSelectedIndex (); refresh (); }//GEN-LAST:event_memberlistActionPerformed private void changejavadocActionPerformed (java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changejavadocActionPerformed if (refreshing) return; saveCurrent (); currMember = -1; refresh (); }//GEN-LAST:event_changejavadocActionPerformed private void leavejavadocaloneActionPerformed (java.awt.event.ActionEvent evt) {//GEN-FIRST:event_leavejavadocaloneActionPerformed if (refreshing) return; saveCurrent (); currMember = -1; refresh (); }//GEN-LAST:event_leavejavadocaloneActionPerformed private void showmembersourcebuttonActionPerformed (java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showmembersourcebuttonActionPerformed List thisMembers = (List) members.get (curr); MemberInfo mi = (MemberInfo) thisMembers.get (currMember); OpenCookie open = (OpenCookie) mi.element.getCookie (OpenCookie.class); if (open != null) open.open (); else pw.println ("Could not open member"); // [PENDING] }//GEN-LAST:event_showmembersourcebuttonActionPerformed private void showclasssourcebuttonActionPerformed (java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showclasssourcebuttonActionPerformed PromptableItem pi = (PromptableItem) sortedPrompts.get (curr); OpenCookie open = (OpenCookie) pi.clazz.getCookie (OpenCookie.class); if (open != null) open.open (); else pw.println ("Could not open class"); // [PENDING] }//GEN-LAST:event_showclasssourcebuttonActionPerformed private void cancelbuttonActionPerformed (java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelbuttonActionPerformed closer.run (); }//GEN-LAST:event_cancelbuttonActionPerformed private void runbuttonActionPerformed (java.awt.event.ActionEvent evt) {//GEN-FIRST:event_runbuttonActionPerformed runbutton.setEnabled (false); saveCurrent (); RequestProcessor.postRequest (new Runnable () { public void run () { for (int i = 0; i < size; i++) { PromptableItem pi = (PromptableItem) sortedPrompts.get (i); pw.println ("Processing " + pi.className); // [PENDING] if (((Boolean) changeSvuid.get (i)).booleanValue ()) { pw.println ("Assigning new SVUID constant"); // [PENDING] try { SVUIDAction.assign (pi.clazz, pi.idealSvuid, pw); } catch (SourceException se) { se.printStackTrace (pw); } } if (((Boolean) changeJavadoc.get (i)).booleanValue ()) { pw.println ("Updating serialization-related Javadoc"); // [PENDING] List thisMembers = (List) members.get (i); for (int j = 0; j < thisMembers.size (); j++) { MemberInfo mi = (MemberInfo) thisMembers.get (j); pw.println ("Updating for " + mi.name); // [PENDING] String doc = mi.doc; if (! doc.equals (UNDOCD)) { JavaDoc javadoc = mi.isMethod ? (JavaDoc) ((MethodElement) mi.element).getJavaDoc () : (JavaDoc) ((FieldElement) mi.element).getJavaDoc (); String name = mi.isMethod ? "@serialData" : "@serial"; JavaDocTag[] tags = javadoc.getTags (name); if (! (tags.length == 1 && tags[0].text ().equals (mi.doc))) { try { if (tags.length > 0) { javadoc.changeTags (tags, JavaDoc.REMOVE); } javadoc.changeTags (new JavaDocTag[] { JavaDocSupport.createTag (name, mi.doc) }, JavaDoc.ADD); } catch (SourceException se2) { se2.printStackTrace (pw); } } else { pw.println ("...to be left alone"); } } else { pw.println ("...to be left undocumented"); } } } SVUIDAction.save (pi.clazz, pw); } closer.run (); } }); }//GEN-LAST:event_runbuttonActionPerformed private void nextbuttonActionPerformed (java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextbuttonActionPerformed saveCurrent (); curr++; currMember = -1; refresh (); }//GEN-LAST:event_nextbuttonActionPerformed private void prevbuttonActionPerformed (java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevbuttonActionPerformed saveCurrent (); curr--; currMember = -1; refresh (); }//GEN-LAST:event_prevbuttonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPanel jPanel1; private javax.swing.JLabel numbering; private javax.swing.JLabel classname; private javax.swing.JButton showclasssourcebutton; private javax.swing.JPanel jPanel2; private javax.swing.JButton prevbutton; private javax.swing.JButton nextbutton; private javax.swing.JButton runbutton; private javax.swing.JButton cancelbutton; private javax.swing.JPanel jPanel3; private javax.swing.JPanel serialpanel; private javax.swing.JLabel jLabel3; private javax.swing.JTextField currsvuid; private javax.swing.JLabel jLabel4; private javax.swing.JTextField newsvuid; private javax.swing.JLabel jLabel6; private javax.swing.JCheckBox changesvuid; private javax.swing.JPanel fieldspanel; private javax.swing.JRadioButton leavejavadocalone; private javax.swing.JRadioButton changejavadoc; private javax.swing.JPanel jPanel6; private javax.swing.JComboBox memberlist; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JEditorPane javadocpane; private javax.swing.JButton showmembersourcebutton; private javax.swing.JLabel extrafieldslabel; // End of variables declaration//GEN-END:variables }